
#include <QByteArray>
#include <QHash>

#include "geometry/edge3d.h"

Edge3D::Edge3D(const QVector3D& rkP1, const QVector3D& rkP2)
    : m_pkP1(&rkP1),
      m_pkP2(&rkP2)
{
}

Edge3D::~Edge3D()
{
}

Edge3D::Edge3D(const Edge3D& rkOther)
    : m_pkP1(&(rkOther.p1())),
      m_pkP2(&(rkOther.p2()))
{
}

Edge3D& Edge3D::operator=(const Edge3D& rkOther)
{
    // Self-assignment.
    if(this == &rkOther)
        return *this;

    // Otherwise simply copy.
    m_pkP1 = rkOther.m_pkP1;
    m_pkP2 = rkOther.m_pkP2;

    return *this;
}

bool Edge3D::isValid() const
{
    // Only a connection beetween two different vertex is valid.
    return m_pkP1 != m_pkP2;
}

const QVector3D& Edge3D::p1() const
{
    return *m_pkP1;
}

const QVector3D& Edge3D::p2() const
{
    return *m_pkP2;
}

qreal Edge3D::x1() const
{
    return m_pkP1->x();
}

qreal Edge3D::y1() const
{
    return m_pkP1->y();
}

qreal Edge3D::z1() const
{
    return m_pkP1->z();
}

qreal Edge3D::x2() const
{
    return m_pkP2->x();
}

qreal Edge3D::y2() const
{
    return m_pkP2->y();
}

qreal Edge3D::z2() const
{
    return m_pkP2->z();
}

QVector3D Edge3D::toVector3D() const
{
    return *m_pkP2 - *m_pkP1;
}

bool Edge3D::operator == (const Edge3D& rkOther) const
{
    return (m_pkP1 == rkOther.m_pkP1 && m_pkP2 == rkOther.m_pkP2) ||
            (m_pkP1 == rkOther.m_pkP2 && m_pkP2 == rkOther.m_pkP1);
}

bool Edge3D::operator != (const Edge3D& rkOther) const
{
    return !(*this == rkOther);
}

uint qHash(const Edge3D& rkEdge)
{
    QVector3D* pkP1 = &const_cast< QVector3D& >(rkEdge.p1());
    QVector3D* pkP2 = &const_cast< QVector3D& >(rkEdge.p2());

    return qHash(pkP1) + qHash(pkP2) + qHash(QByteArray("Edge3D"));
}

